前后端分离的项目 您所在的位置:网站首页 前后端分离 分页 前后端分离的项目

前后端分离的项目

2024-02-20 23:11| 来源: 网络整理| 查看: 265

问题:

在前后端分离的项目中,涉及到多表数据展示,过滤,分页的实现过程

解决办法: 一、后端接口的实现 1.路由(urls文件): from django.urls import path from . import views urlpatterns = [ path(r"category/", views.CourseCategoryListAPIView.as_view()), path(r"courses/", views.CourseListAPIView.as_view()), ] 2.视图

因为只涉及数据的展示,故继承ListAPIView,指定查询集和序列化器 过滤:添加属性filter_fields;分页:添加属性pagination_class。关于过滤和分页的详解:移步另一篇博客

from rest_framework.generics import ListAPIView from . import models from .serializers import CourseCategoryModelSerializer, CourseListModelSerializer from .pagenations import LargeResultsSetPagination class CourseCategoryListAPIView(ListAPIView): """ 课程分类 """ queryset = models.CourseCategory.objects.filter(is_show=True, is_deleted=False).order_by("orders", "-id") serializer_class = CourseCategoryModelSerializer class CourseListAPIView(ListAPIView): """ 课程列表 """ queryset = models.Course.objects.filter(is_deleted=False, is_show=True).order_by('id') # 可以按id倒序 serializer_class = CourseListModelSerializer # 可按字段course_category过滤,前端发请求时www.xxxx/xx/?course_category=1可拿到course_category=1的数据 filter_fields = ('course_category',) # 需要自定义类LargeResultsSetPagination继承PageNumberPagination pagination_class = LargeResultsSetPagination

关于过滤: 1)需要安装django-filter

pip3 install django-filter 配置setting文件 (注册应用,配置REST_FRAMEWORK) INSTALLED_APPS = [ ... 'django_filters', #注册应用 ] REST_FRAMEWORK = { ... 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) }

关于分页: 自定义的类:

from rest_framework.pagination import PageNumberPagination class LargeResultsSetPagination(PageNumberPagination): page_size = 2 # 默认每一页显示的数据量 # http://127.0.0.1:8000/use03/student8/?pp=1&size=3 # page_query_param = 'pp' # 自定义页码的参数名 page_size_query_param = 'size' # 允许客户端通过get参数来控制每一页的数据量 max_page_size = 5 # 客户端通过size指定获取数据的条数时,最大不能超过多少 3.序列化器

序列化器如下,注意正向查询多对一的处理,和反向查询一对多的跨表查询

from rest_framework import serializers from . import models class CourseCategoryModelSerializer(serializers.ModelSerializer): """ 课程分类序列化器 """ class Meta: model = models.CourseCategory fields = ["id", "name"] class TeacherModelSerializer(serializers.ModelSerializer): class Meta: model = models.Teacher fields = ['name', 'role', 'title', 'signature'] class CourseListModelSerializer(serializers.ModelSerializer): """ 课程列表序列化器 前端需要的数据: 1.单表查询:课程名称,课程封面,学习人数,总课时数量,课时更新数量,价格, 2.正向多对一查询:老师姓名,讲师身份,职位,导师签名 有两种方式: 方式一:teacher_name = serializers.CharField(source='teacher.name') #自定义字段,通过sourse关键字就能获取外键关联的指定字段数据,别忘了在fields里面指定一下 方式二:序列化器的嵌套,此处用方式二 3.跨表反向查询:课时列表(反向跨章节列表) 通过在models.Course中自定义方法实现 """ teacher = TeacherModelSerializer() class Meta: model = models.Course fields = ['id', 'name', 'course_img', 'students', 'lessons', 'pub_lessons', 'price', 'teacher', 'get_lessons', ]

在models中自定义的方法(两次反向查询):

def get_lessons(self): chapters = self.coursechapters.all() # 反向查询,通过related_name(如果没有该参数通过小写表名_set) lession_list = [] for chapter in chapters: # 反向查询,通过章节查询章节对应的所有课时 lessons = chapter.coursesections.filter(is_show_list=True, is_show=True, is_deleted=False) for lesson in lessons: lession_list.append({ 'name': lesson.name, 'free_trail': lesson.free_trail, 'lesson': lesson.lesson, # 第几课时 }) return lession_list[:4]

注意: 当外键字段有参数related_name时反向查询则通过对象.related_name反向查询,如:

course = models.ForeignKey("Course", related_name='coursechapters', on_delete=models.CASCADE, verbose_name="课程名称") 实现效果:

分页: 前端页面可以通过如下路径拿到结果 res.count得到数据总数;res.results得到数据内容 在这里插入图片描述 过滤: 在这里插入图片描述

二、前端实现

过滤通过vue监听属性实现,分页用element-ui实现, js代码如下:

import Vheader from "./common/Vheader" import Footer from "./common/Footer" export default { name: "Course", data(){ return{ category:0, // 默认分类值 category_list:'', // 课程分类列表 course_list:'', // 课程列表 fitlers:{}, // 过滤,分页时用get请求参数 total:0, // 总的数据条数,分页时用到 } }, components:{ Vheader, Footer, }, created() { this.get_course_category(); this.get_course(); }, // 过滤,监听标签属性 watch: { category(){ if (this.category>0){ this.fitlers['course_category'] = this.category; }else{ this.fitlers={} } this.get_course(); } }, methods: { // 获取课程分类信息 get_course_category() { this.$axios.get(`${this.$settings.Host}/course/category/`) .then(response => { //console.log(response.data) this.category_list = response.data; }) }, // 获取课程列表 get_course(){ this.$axios.get(`${this.$settings.Host}/course/courses/`,{ params:this.fitlers, }) .then((res)=>{ this.total = res.data.count this.course_list = res.data.results }) }, // currentPage改变时会触发 (page改变时触发) val为page的改变值 handleCurrentChange(val) { this.fitlers['page'] = val this.get_course(); }, // pageSize改变时会触发 (size改变时触发) val为size的改变值 handleSizeChange(val) { this.fitlers['size'] = val this.get_course(); } } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有